package org.ttitfly.ttcore.mybatis;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.hibernate.QueryException;
import org.ttitfly.ttcore.util.log.LogMessageUtil;
import org.ttitfly.ttcore.util.query.SearchObject;
/**
 * @author ttitfly
 */
public abstract class BaseSqlMapDAO<T> {

    private SqlSessionFactory sqlMapper = SqlMapClientHolder.getInstance().getSqlMapper();
    
    /**
     * if sqlmapping include chinese character ,have to fix the charset
     */
    static {
        Resources.setCharset(Charset.forName("UTF-8"));
    }

    private static final Log logger = LogFactory.getLog(BaseSqlMapDAO.class);

    protected int getPaginatedListCount(String statementName, SearchObject searchObject) {
        Long startTime = System.currentTimeMillis();
        SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
        try {
            List<?> retList = session.selectList(statementName, searchObject);
            return retList.size() > 0 ? (Integer) retList.get(0) : 0;
        } catch (Exception e) {
            logger.error(LogMessageUtil.printStack(e));
            throw new QueryException(e);
        } finally {
            session.close();
            logger.debug("Total record count loading took " + (System.currentTimeMillis() - startTime));
        }

    }


    @SuppressWarnings("unchecked")
	protected  List<T> getPaginatedList(String statementName, SearchObject searchObject) {
        Long startTime = System.currentTimeMillis();
        if (searchObject.isExportFull()) {
            return getQueryList(statementName, searchObject);
        }

        SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
        try {
        	if(searchObject.getCurrentPage() <=0 ){
        		searchObject.setCurrentPage(1);
        	}
            RowBounds rowBounds = new RowBounds((searchObject.getCurrentPage() - 1) * searchObject.getPageSize(), searchObject
                    .getPageSize());

            List<T> retList = session.selectList(statementName, searchObject, rowBounds);
            return retList;
        } catch (Exception e) {
            logger.error(LogMessageUtil.printStack(e));
            throw new QueryException(e);
        } finally {
            session.close();
            logger.debug("One page record loading took " + (System.currentTimeMillis() - startTime));
        }
    }

    @SuppressWarnings("unchecked")
	public List<T> getQueryList(String statementName, SearchObject searchObject) {
        Long startTime = System.currentTimeMillis();
        SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
        try {
            List<T> retList = session.selectList(statementName, searchObject);
            return retList;
        } catch (Exception e) {
            logger.error(LogMessageUtil.printStack(e));
            throw new QueryException(e);
        } finally {
            session.close();
            logger.debug("Record loading took " + (System.currentTimeMillis() - startTime));
        }
    }


    @SuppressWarnings("unchecked")
	public List<T> getQueryList(String statementName, Map inputParameter) {
        Long startTime = System.currentTimeMillis();
        SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
        try {
            List<T> retList = session.selectList(statementName, inputParameter);
            return retList;
        } catch (Exception e) {
            logger.error(LogMessageUtil.printStack(e));
            throw new QueryException(e);
        } finally {
            session.close();
            logger.debug("Record loading took " + (System.currentTimeMillis() - startTime));
        }
    }

    @SuppressWarnings( { "unchecked"})
    public  List<T> getQueryList(String statementName, List inputParameter) {
        Long startTime = System.currentTimeMillis();
        SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
        try {
            List<T> retList = session.selectList(statementName, inputParameter);
            return retList;
        } catch (Exception e) {
            logger.error(LogMessageUtil.printStack(e));
            throw new QueryException(e);
        } finally {
            session.close();
            logger.debug("Record loading took " + (System.currentTimeMillis() - startTime));
        }
    }
    
    @SuppressWarnings("unchecked")
	public T getUniqueObject(String statementName, Object inputParameter){
    	   long startTime = System.currentTimeMillis();
           SqlSession session = sqlMapper.openSession(ExecutorType.REUSE);
           try {
               T obj = (T) session.selectOne(statementName, inputParameter);
               return obj;
           } catch (Exception e) {
               logger.error(LogMessageUtil.printStack(e));
               throw new QueryException(e);
           } finally {
               session.close();
               logger.debug("Record loading took " + (System.currentTimeMillis() - startTime));
           }
    }
    
    protected SqlSessionFactory getSqlMapper() {
        return sqlMapper;
    }

}
